package canchas

import scala.collection.mutable.ArrayBuffer
import org.joda.time.DateTime
import org.joda.time.LocalDate
import models.Reserva
import models.ReservaImposibleException

abstract class Cancha() {
  
  val reservas : ArrayBuffer[Reserva] = new ArrayBuffer[Reserva]
  
  /**
   * Responde cual es el precio base de la cancha
   * @return el precio base
   */
  def precioBase(): Float 
  
  /**
   * Analiza cual es el precio total para determinada reserva
   * @param una reserva
   * @return el precio total de la reserva para la cancha
   */
  def precioReserva(r:Reserva) = precioBase()
  
  /**
   * Intenta reservar una cancha
   * @param una reserva
   * @return la cancha resultante de realizar la reserva, o bien lanza una excepcion
   */
  def reservarse(r: Reserva) {
    
    if(libreParaReservar(r)) {
	  if(iluminacionSuficiente(r)) {
        agregarReserva(r)
	  } else throw new ReservaImposibleException("La cancha que desea reservar no tiene luces para el horario deseado")
    } else throw new ReservaImposibleException("La cancha que desea reservar ya esta ocupada")
  }
  
  /**
   * Agrega una reserva a la lista de reservas de la cancha
   * @param una reserva
   */
  def agregarReserva(r: Reserva) {
    reservas += r
  }
  
  /**
   * Analiza si la cancha tiene reservas para determinado dia
   * @param una fecha
   * @return true si la cancha tiene reservas para el dia parametrizado
   */
  def tieneReservasParaElDia(d: LocalDate) = 
    reservas.exists(r => r.fechaHora.toLocalDate().equals(d))
    
  /**
   * Analiza todas las reservas de la cancha, segun su dia
   * @param una fecha
   * @return todas reservas para el dia parametrizado
   */
  def reservasDelDia(d: LocalDate) = 
    reservas.filter(r => r.fechaHora.toLocalDate().equals(d))
    
  /**
   * Recolecta los precios de las reservas de la cancha
   * @return todos los precios de las reservas de la cancha
   */
  def preciosReservas() = 
    reservas.map(r => precioReserva(r))
  
  /**
   * @return la suma de todos los precios recaudados por las reservas de la cancha
   */
  def facturacionTotal() =
    preciosReservas().sum[Float]
    
  /**
   * Evalua si una cancha puede reservarse en determinado momento
   * @param una reserva
   * @return true si la cancha puede reservarse durante el tiempo indicado por la reserva
   */
  def libreParaReservar(r: Reserva): Boolean = 
    reservasDelDia(r.fechaHora.toLocalDate()).forall(rx => !r.seSuperpone(rx))
  
  /**
   * @param una reserva
   * @return true si las condiciones de iluminacion de la cancha son satisfactorias para la reserva parametrizada
   */
  def iluminacionSuficiente(r: Reserva) = !r.esHorarioNocturno() 
  
}
